// common/logger/debugger.util.ts
import { LoggerService } from './logger.service';
import * as util from 'util';

/**
 * 调试工具类
 * 提供各种调试辅助方法
 */
export class Debugger {
  private static logger: LoggerService;

  /**
   * 初始化调试器
   * @param logger 日志服务实例
   */
  static init(logger: LoggerService): void {
    Debugger.logger = logger;
    Debugger.logger.setContext('Debugger');
  }

  /**
   * 打印变量的详细信息
   * @param variable 要打印的变量
   * @param name 变量名称
   * @param options 打印选项
   */
  static dump(
    variable?: any,
    name?: string,
    options: { depth?: number; colors?: boolean } = {},
  ): void {
    if (!Debugger.logger) {
      console.warn('Debugger not initialized. Call Debugger.init() first.');
      return;
    }

    const { depth = 10, colors = true } = options;
    const prefix = name ? `${name} = ` : '';
    const output = prefix + util.inspect(variable, { depth, colors });

    Debugger.logger.debug(output);
  }

  /**
   * 打印函数调用堆栈
   * @param message 可选的消息
   */
  static trace(message?: string): void {
    if (!Debugger.logger) {
      console.warn('Debugger not initialized. Call Debugger.init() first.');
      return;
    }

    const stack = new Error().stack;
    Debugger.logger.debug(`${message ? message + '\n' : ''}${stack}`);
  }

  /**
   * 测量函数执行时间
   * @param fn 要测量的函数
   * @param name 函数名称
   * @returns 函数执行结果
   */
  static async measure<T>(fn: () => Promise<T> | T, name?: string): Promise<T> {
    if (!Debugger.logger) {
      console.warn('Debugger not initialized. Call Debugger.init() first.');
      return fn();
    }

    const label = name || 'Function execution';
    const start = Date.now();

    try {
      const result = await fn();
      const duration = Date.now() - start;
      Debugger.logger.debug(`${label} took ${duration}ms`);
      return result;
    } catch (error: unknown) {
      const duration = Date.now() - start;
      const errorMessage = error instanceof Error ? error.stack : String(error);
      Debugger.logger.error(`${label} failed after ${duration}ms`, errorMessage);
      throw error;
    }
  }

  /**
   * 创建一个装饰器，用于测量方法执行时间
   * @param name 可选的名称（默认使用方法名）
   * @returns 方法装饰器
   */
  static Measure(name?: string) {
    return function (
      target: any,
      propertyKey: string,
      descriptor: PropertyDescriptor,
    ) {
      const originalMethod = descriptor.value;

      descriptor.value = async function (...args: any[]) {
        if (!Debugger.logger) {
          console.warn('Debugger not initialized. Call Debugger.init() first.');
          return originalMethod.apply(this, args);
        }

        const methodName = name || `${target.constructor.name}.${propertyKey}`;
        const start = Date.now();

        try {
          const result = await originalMethod.apply(this, args);
          const duration = Date.now() - start;
          Debugger.logger.debug(`${methodName} took ${duration}ms`);
          return result;
        } catch (error: unknown) {
          const duration = Date.now() - start;
          const errorMessage = error instanceof Error ? error.stack : String(error);
          Debugger.logger.error(`${methodName} failed after ${duration}ms`, errorMessage);
          throw error;
        }
      };

      return descriptor;
    };
  }
}
